package khoihd;

import jade.core.Agent;
import jade.core.behaviours.*;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;

import java.util.*;

public class BookSellerAgent extends Agent {
	private Map catalogue = new HashMap();
	//private BookSellerGui myGui;
	
	
	protected void setup() {
		
		
		//add the serving calls for price from buyer agent
		addBehaviour(new CallForOfferServer());
		
		//add the behaviour serving purchase requests from buyer agent
		//addBehaviour(new PurchaseOrderServer());
		DFAgentDescription dfd = new DFAgentDescription();
		dfd.setName(getAID());
		ServiceDescription sd = new ServiceDescription();
		sd.setType("Book-selling");
		sd.setName(getLocalName() + "Book-selling");
		dfd.addServices(sd);
		try {
			DFService.register(this, dfd);
		}
		catch (FIPAException fe) {
			fe.printStackTrace();
		}
	}
	
	protected void takeDown() {
		System.out.println("Seller-agent " + getAID().getName() + " terminated.");
		try {
			DFService.deregister(this);
		}
		catch (FIPAException fe) {
			fe.printStackTrace();
		}
	}
	
	//called by GUI
	public void putForSale(String title, int initPrice, int minPrice, Date deadline) {
		addBehaviour(new PriceManager(this, title, initPrice, minPrice, deadline));
	}
	
	private class PriceManager extends TickerBehaviour {
		private String title;
		private int initPrice, currentPrice, deltaP;
		private long initTime, deadline, deltaT;
		
		private PriceManager(Agent a, String t, int ip, int mp, Date d) {
			super(a, 60000);
			title = t;
			initPrice = ip;
			currentPrice = initPrice;
			deltaP = initPrice - mp;
			deadline = d.getTime();
			initTime = System.currentTimeMillis();
		}

		public void onStart() {
			catalogue.put(title, this);
			super.onStart();
		}
		
		protected void onTick() {
			// TODO Auto-generated method stub
			long currentTime = System.currentTimeMillis();
			if (currentTime > deadline) {
				catalogue.remove(title);
				stop();
			}
			else {
				long elapsedTime = currentTime - initTime;
				currentPrice = (int) (initPrice - deltaP * (elapsedTime / deltaT));
			}
		}
		
		public int getCurrentPrice() {
			return currentPrice;
		}
	}
	
	private class CallForOfferServer extends CyclicBehaviour {
		
		private MessageTemplate mt = MessageTemplate.MatchPerformative(ACLMessage.CFP);
		
		public void action() {
			// TODO Auto-generated method stub
			ACLMessage msg = myAgent.receive(mt);
			if (msg != null) {
				String title = msg.getContent();
				ACLMessage reply = msg.createReply();
				
				PriceManager pm = (PriceManager) catalogue.get(title);
				if (pm != null) {
					reply.setPerformative(ACLMessage.PROPOSE);
					reply.setContent(String.valueOf(pm.getCurrentPrice()));
				}
				else {
					reply.setPerformative(ACLMessage.REFUSE);
				}
				myAgent.send(reply);
			}
			else {
				block();
			}
		}
		
		
	}
	
	
	
}
